package org.webrtc.ui;

import java.io.IOException;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Vibrator;
import android.util.Log;

public final class AudioUtil {
	// ------------------------------ FIELDS ------------------------------

	private static final String TAG = "AudioUtil";

	private final AudioManager mAudioManager;

	private AudioMode mAudioMode;

	private final Context mContext;

	private final OnAudioChangeListener mListener;

	private final BroadcastReceiver mReceiver = new AudioBroadcastReceiver();

	private boolean mWiredHeadsetEnabled;

	private MediaPlayer mAudio;

	private Uri mUri;

	private static int currVolume;
	private static int oldmode = -1;
	public static int speakermode = -1;
	private final static long[] vibratePattern = { 0, 1000, 1000 };

	private Ringtone oRingtone;

	// --------------------------- CONSTRUCTORS ---------------------------

	public AudioUtil(final Context context, final OnAudioChangeListener listener) {
		mContext = context;
		mListener = listener;
		mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
		oldmode = mAudioManager.getMode();

		initReceiver();
	}

	// -------------------------- OTHER METHODS --------------------------

	public void destroy() {
		// unregister the receiver
		mAudioManager.setMode(oldmode);
		mContext.unregisterReceiver(mReceiver);
	}

	public boolean isHeadsetOn() {
		return mAudioMode == AudioMode.DEVICE;
	}

	public boolean isSpeakerOn() {
		Log.d(TAG, " - isSpeakerphoneOn: " + mAudioManager.isSpeakerphoneOn());
		return mAudioManager.isSpeakerphoneOn();
	}

	public void toggleSpeaker() {
		if (isSpeakerOn()) {
			turnOnHeadset();
		} else {
			turnOnSpeaker();
		}
	}

	public void turnOnHeadset() {
		switchAudioMode(AudioMode.DEVICE);
	}

	public void turnOnSpeaker() {
		switchAudioMode(AudioMode.SPEAKER);
	}

	public void turnOnWiredHeadset() {
		if (mWiredHeadsetEnabled) {
			switchAudioMode(AudioMode.EARPIECE);
		}
	}

	public void setSpeakOff() {
		int mode = mAudioManager.getMode();
		Log.i("zouzimode", "mode:" + mode);
		mAudioManager.setSpeakerphoneOn(false);

		if (mListener != null) {
			mListener.onAudioChange();
		}
	}

	public void setDefault() {
		mAudioManager.setMode(mAudioManager.isWiredHeadsetOn() ? AudioManager.MODE_IN_CALL : AudioManager.MODE_NORMAL);
	}

	public boolean wiredHeadsetEnabled() {
		return mWiredHeadsetEnabled;
	}

	private void initReceiver() {
		IntentFilter intentFilter = new IntentFilter(Intent.ACTION_HEADSET_PLUG);
		mContext.registerReceiver(mReceiver, intentFilter);
	}

	private int getAndroidSDKVersion() {
		int version = 0;
		try {
			version = Integer.valueOf(android.os.Build.VERSION.SDK);
		} catch (NumberFormatException e) {
		}
		return version;
	}

	private void switchAudioMode(AudioMode mode) {
		Log.d(TAG, " - switching audio to " + mode.toString());

		mAudioManager.setWiredHeadsetOn(mode == AudioMode.EARPIECE);
		mAudioManager.setSpeakerphoneOn(mode == AudioMode.SPEAKER);
		mAudioMode = mode;
		if (mListener != null) {
			mListener.onAudioChange();
		}
	}

	// private void switchAudioMode(AudioMode mode) {
	// Log.d(TAG, " - switching audio to " + mode.toString());
	// mAudioManager.setWiredHeadsetOn(mode == AudioMode.EARPIECE);
	// int sdk = getAndroidSDKVersion();
	// Log.i("zouzi", "sdk:" + sdk);
	// if (sdk >= 14) {
	// if (mode == AudioMode.SPEAKER) {
	// mAudioManager.setMode(mAudioManager.MODE_IN_CALL);
	// }
	// mAudioManager.setSpeakerphoneOn(mode == AudioMode.SPEAKER);
	// } else {
	// if (mode == AudioMode.SPEAKER) {
	// OpenSpeaker();
	// } else
	// CloseSpeaker();
	// }
	//
	// //
	//
	// mAudioMode = mode;
	// if (mListener != null) {
	// mListener.onAudioChange();
	// }
	// }

	// 打开扬声器
	public void OpenSpeaker() {

		try {
			AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
			audioManager.setMode(AudioManager.ROUTE_SPEAKER);
			currVolume = audioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL);

			audioManager.setSpeakerphoneOn(true);
			Log.i("zouzi", "open speaker");
			audioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL, audioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL), AudioManager.STREAM_VOICE_CALL);

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// 关闭扬声器
	public void CloseSpeaker() {

		try {
			AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
			if (audioManager != null) {

				audioManager.setSpeakerphoneOn(false);
				audioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL, currVolume, AudioManager.STREAM_VOICE_CALL);

			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		// Toast.makeText(context,"揚聲器已經關閉",Toast.LENGTH_SHORT).show();
	}

	public void setUri(Uri uri) {
		mUri = uri;
	}

	public void startRingtone() {
		android.os.Vibrator v = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
		v.vibrate(vibratePattern, 1);
		oRingtone = RingtoneManager.getRingtone(mContext, RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE));

		if (oRingtone != null)
			oRingtone.play();
	}

	public void stopRingtone() {
		android.os.Vibrator v = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
		v.cancel();
		// mAudioManager.setMode(AudioManager.MODE_IN_CALL);
		if (oRingtone != null) {
			Ringtone ringtone = oRingtone;
			oRingtone = null;
			ringtone.stop();

		}

	}

	/**
	 * Plays the ringtone.
	 */
	public void play() {
		mAudioManager.setMode(AudioManager.MODE_IN_CALL);
		mAudioManager.setStreamVolume(AudioManager.MODE_IN_CALL, mAudioManager.getStreamMaxVolume(AudioManager.MODE_IN_CALL)/2, 0);
		if (mAudio == null) {
			try {
				openMediaPlayer();
			} catch (Exception ex) {
				Log.e(TAG, "play() caught ", ex);
				mAudio = null;
			}
		}
		if (mAudio != null) {
			// do not ringtones if stream volume is 0
			// (typically because ringer mode is silent).
			
			if (mAudioManager.getStreamVolume(AudioManager.MODE_RINGTONE) != 0) {
				mAudio.start();
			}
		}
	}

	/**
	 * Stops a playing ringtone.
	 */
	public void stop() {
		mAudioManager.setMode(AudioManager.MODE_NORMAL);
		if (mAudio != null) {
			mAudio.reset();
			mAudio.release();
			mAudio = null;
			// mAudioManager.setMode(AudioManager.MODE_IN_CALL);
		}
	}

	private void openMediaPlayer() throws IOException {
		mAudio = new MediaPlayer();
		if (mUri != null) {
			mAudio.setDataSource(mContext, mUri);
		} else
			throw new IOException("No data source set.");

		mAudio.setAudioStreamType(AudioManager.MODE_NORMAL);
		mAudio.setLooping(true);
		mAudio.prepare();
	}

	// -------------------------- ENUMERATIONS --------------------------

	public enum AudioMode {
		SPEAKER, EARPIECE, BLUETOOTH, DEVICE
	}

	// -------------------------- INNER CLASSES --------------------------

	public interface OnAudioChangeListener {
		void onAudioChange();
	}

	class AudioBroadcastReceiver extends BroadcastReceiver {
		@Override
		public void onReceive(Context context, Intent intent) {
			String action = intent.getAction();
			if (action.equals(Intent.ACTION_HEADSET_PLUG)) {
				int state = intent.getIntExtra("state", 0);
				mWiredHeadsetEnabled = (state == 1);
				if (mWiredHeadsetEnabled) {
					turnOnWiredHeadset();
					return;
				}
			}
			turnOnHeadset();
		}
	}
}
